<?php
###########################################################################
#  Copyright (C) 2006-2007 Glyphix, Inc. <briz@glyphix.com>               #
#                                                                         #
#  Permission is hereby granted, free of charge, to any person obtaining  #
#  a copy of this software and associated documentation files (the        #
#  "Software"), to deal in the Software without restriction, including    #
#  without limitation the rights to use, copy, modify, merge, publish,    #
#  distribute, sublicense, and/or sell copies of the Software, and to     #
#  permit persons to whom the Software is furnished to do so, subject to  #
#  the following conditions:                                              #
#                                                                         #
#  The above copyright notice and this permission notice shall be         #
#  included in all copies or substantial portions of the Software.        #
#                                                                         #
#  Except as contained in this notice, the name(s) of the above           #
#  copyright holders shall not be used in advertising or otherwise to     #
#  promote the sale, use or other dealings in this Software without       #
#  prior written authorization.                                           #
#                                                                         #
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        #
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     #
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. #
#  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR      #
#  OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,  #
#  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR  #
#  OTHER DEALINGS IN THE SOFTWARE.                                        #
###########################################################################

/**
 * GXObject
 *
 * GXPage uses GXObject to instantiate the classes called for in Site.xml.
 * GXObject caches each object instance so that only one instance of any object exists.
 * @author		Brad Brizendine <briz@glyphix.com>
 * @link		http://www.glyphix.com/
 * @license		http://opensource.org/licenses/bsd-license.php BSD License
 * @version		1.0
 * @package		GXPage
 * @subpackage	Engine
 * @copyright	Copyright 2006 - 2007, Glyphix, Inc.
 */

class GXObject {

	// cache instantiated objects
	private static $cache;

	// Object var to ensure only one instance of this object
    private static $instance = NULL;
	// Method to call to instantiate this class
	public static function getInstance( $className = __CLASS__ ){
		if( !isset(self::$instance) ){
			self::$instance = new $className();
		}
		return self::$instance;
	}

	// nothing to construct
	private function __construct(){
		return true;
	}

	// returns a reference to the object instance with the provided class name
	public static function get( $name = null, $alias = null, $args = null, $load = true ){
		// set the name
		$objName = ($alias) ? $alias : $name;
		if( !$objName ){
			trigger_error( 'Missing name', E_USER_ERROR );
			return false;
		}

		// hide any invalid index errors
		if( !isset(self::$cache[ $objName ]) ){
			trigger_error( 'No object by that name is cached: ' .$name, E_USER_WARNING );
			if( $load ){
				trigger_error( 'Returning load(' .$name .',' .$alias .',' .gettype($args) .')', E_USER_WARNING );
				return self::load( $name, $alias, $args );
			}
			return false;
		}
		return self::$cache[ $objName ];
	}

	// instantiate and cache the named object
	public static function load( $name = null, $alias = null, $args = null ){
		if( !$name ){
			trigger_error( 'Missing name', E_USER_ERROR );
			return false;
		}

		// set the name
		$cacheName = ($alias) ? $alias : $name;

		// attempt to instantiate the class (name, not the alias)
		// try to call getInstance
		//eval('$obj = ' .$name .'::getInstance(' .$name .');');
		try{
			$obj =& new $name($args);
		}catch(Exception $e){
			trigger_error( 'Unable to load object ' .$name .': ' .print_r($e,true), E_USER_ERROR );
			return false;
		}
		self::cache( $obj, $cacheName );
		trigger_error( 'Loaded object ' .$cacheName, E_USER_WARNING );
		return self::get($cacheName);
	}

	// cache the provided object instance by its class name
	private static function cache( &$obj, $alias = null ){
		if( !is_object($obj) ){
			trigger_error( 'Obj is not an object' , E_USER_ERROR );
			return false;
		}

		// set the correct name
		$cacheName = ($alias) ? $alias : get_class($obj);

		self::$cache[ $cacheName ] =& $obj;
		return true;
	}

	// run the specified method with the provided args
	public static function run( $obj = null, $method = null, $args = array() ){
		// if we have a string, get the object
		if( is_string($obj) ){
			if( !($obj = self::get($obj)) ){
				trigger_error( 'Unable to obtain an object by that name: ' .$name, E_USER_ERROR );
				return false;
			}
		}
		// sanity check
		if( !is_object($obj) || !$method ){
			trigger_error( 'get_class(' .$obj .') is not an object, or no method to call', E_USER_ERROR );
			return false;
		}
		if( !method_exists($obj,$method) ){
			trigger_error( 'Unable to find ' .$name .'::' .$method, E_USER_ERROR );
			return false;
		}
		// now attempt to execute the requested action
		if( !($result = call_user_func_array( array(&$obj,$method), $args )) ){
			trigger_error( 'Unable to exec ' .get_class($obj) .'::' .$method, E_USER_ERROR );
			return false;
		}
		// return the raw results from the object call
		return $result;
	}

}

?>